/*
读一点，写一点
*/
//fs.open、fs.read、fs.write、fs.close

const fs = require('fs');
const path = require('path');

const resolve = (filename) => {
  return path.resolve(__dirname, filename);
};

/*
flag参数↓

符号	含义
r	读文件，文件不存在报错
r+	读取并写入，文件不存在报错
rs	同步读取文件并忽略缓存
w	写入文件，不存在则创建，存在则清空(fs.writeFile默认flag)
wx	排它写入文件
w+	读取并写入文件，不存在则创建，存在则清空
wx+	和w+类似，排他方式打开
a	追加写入
ax	与a类似，排他方式写入
a+	读取并追加写入，不存在则创建
ax+	作用与a+类似，但是以排他方式打开文件

w+ 相较于 r+ 文件不存在会创建 而r+则是报错
a+
x 表示排他方式 写的时候会锁住文件 别人就不能再操作了

另外fs.open和fs.write在flag参数之后还有个mode参数，主要用来在新建文件时写入权限（读写执行的权限）

权限分为三组
我自己的权限:我所在组的权限:其他人的权限

读取2 写入4 执行1
*/

// fs.writeFileSync(resolve('d.txt'), '123', {flag: 'a'}); //在文件末尾进行追加
//↕等价
// fs.appendFileSync(resolve('d.txt'), 'aaa');


fs.open(resolve('a.txt'), 'r', (err, rfd) =>{ //fd-> file descriptor
  fs.open(resolve('e.txt'), 'w', 0o666/* linux权限，最大0o777(8进制) */, (err, wfd)=>{
    console.log('rfd:',rfd); //是个数字 window从3开始 mac从20开始，用来表示打开的文件，fd最高为1024(linux中)
    console.log('wfd:',wfd);

    // 读取 是 往电脑的内存中写入
    // 写入 是 读取内存中的数据写入到磁盘中
    const buffer = Buffer.alloc(3); //← 这样占用的内存只有3个字节，当第一次读取以及写入完毕，第二次读取到的会覆盖第一次读取到的

    let roffset = 0;
    let woffset = 0;

    let next = () => {
      fs.read(rfd,buffer/*读取到哪个内存中*/,0/*从指定buffer的那个位置开始写入*/,3/*写入几个*/,roffset/*从文件哪个位置开始读取*/,(err,bytesRead)=>{
        if(err){
          fs.close(rfd,()=>{});
          fs.close(wfd,()=>{});
        }
        // console.log('bytesRead',bytesRead);
        // console.log(buffer.toString());
        if(bytesRead === 0){
          fs.close(rfd,()=>{});
          fs.close(wfd,()=>{});
          console.log('文件拷贝完毕')
        }else{
          roffset += bytesRead;
          fs.write(wfd, buffer/*从哪个buffer中读取*/, 0/*从哪个位置开始读取*/, 3/*读取几个*/, woffset/*写到第几个位置*/, (err, bytesWritten) => {
            if(err){
              fs.close(rfd,()=>{});
              fs.close(wfd,()=>{});
            }
            // console.log('bytesWritten',bytesWritten);
            console.log('buffer:', buffer);
            woffset += bytesWritten;
            next();
          });
        }
      });
    };
    next();
  });

});


/*
TODO 注意 写入系列api  fs.writeFile/fs.write 或则fs.createWriteStream ws.write
 都 可以写入字符串 和 buffer，如果写入的是字符串，需要注意以何种编码方式写入
*/
